package api.action;

import api.model.ApiAuthInter;
import api.model.ApiAuthinfo;
import api.model.ApiColumn;
import api.model.ApiTable;
import api.service.ApiAuthinfoService;
import com.alibaba.fastjson.JSONObject;
import m.common.action.ActionMeta;
import m.common.action.RequestMeta;
import m.common.action.VueResult;
import m.common.model.type.FieldType;
import m.common.model.util.*;
import m.html.VueCollectResult;
import m.html.collect.CollectColumn;
import m.html.collect.CollectColumnType;
import m.html.element.attr.Align;
import m.html.element.attr.ButtonType;
import m.html.element.other.DisplayItem;
import m.html.element.other.Param;
import m.html.list.EventType;
import m.html.list.ListButton;
import m.html.list.ListEvent;
import m.system.cache.CacheUtil;
import m.system.db.TransactionManager;
import m.system.exception.MException;
import m.system.handler.HandlerUtil;
import m.system.util.*;
import manage.action.ManageAction;
import manage.model.AdminLogin;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@ActionMeta(name="api/apiInter")
public class ApiInterAction extends ManageAction {
    private JSONObject model;
    private Map<String, Object> executeModel(ApiAuthInter inter,JSONObject model,AdminLogin admin) throws Exception {
        if(!ArrayUtil.isEmpty(inter.getDataHandler())){
            return HandlerUtil.executes(model,admin,inter.getDataHandler());
        }else{
            return model.getInnerMap();
        }
    }
    @RequestMeta(params = {"name"})
    public JSONMessage execute(String name) throws Exception {
        //所有鉴权接口都调用这个方法。
        //在urlmarker.xml定义重定向
        //   /api/inter/[name]  >>>  /action/api/apiInter/execute?name=[name]
        JSONMessage result=new JSONMessage(0);
        String auth=getAuthorization();
        if(StringUtil.isSpace(auth)) throw new MException(this.getClass(),"无鉴权信息");
        AdminLogin admin=getService(ApiAuthinfoService.class).auth(auth, ApiAuthinfo.Type_Inter, true);
        String authId=auth.split(" ")[1];
        ApiAuthInter inter=CacheUtil.get(ApiAuthInter.class,authId,name);
        SystemUtil.println("-----",inter);
        String msg="";
        TransactionManager tm=new TransactionManager();
        try {
            tm.begin();
            if ("A".equals(inter.getType())) {
                Map<String, Object> map;
                if (null == model.get("oid") || StringUtil.isSpace(model.get("oid").toString())) {
                    //不存在oid属性
                    model.put("oid", GenerateID.generatePrimaryKey());
                    map=executeModel(inter,model,admin);
                    TableUpdateUtil.insertModel(inter.getModelTable().getOid(), map);
                    msg = "保存成功";
                } else if (!TableQueryList.getList(inter.getModelTable().getOid(), new String[]{"oid"}, null, QueryCondition.eq("oid", model.get("oid"))).isEmpty()) {//oid在库
                    map=executeModel(inter,model,admin);
                    TableUpdateUtil.updateModel(inter.getModelTable().getOid(), map);
                    msg = "修改成功";
                } else {//oid不在库
                    model.put("oid", model.get("oid"));
                    map=executeModel(inter,model,admin);
                    TableUpdateUtil.insertModel(inter.getModelTable().getOid(), map);
                    msg = "保存成功";
                }
                result.push("model", map);
            } else if ("B".equals(inter.getType())) {
                if (null == getPage()) setPage(new QueryPage());
                String[] fields = ArrayUtil.concat(new String[]{"*"}, inter.getSubTables());
                for (int i = 0; i < fields.length; i++) {
                    if (!fields[i].contains("*")) {
                        fields[i] = fields[i] + ".*";
                    }
                }
                List<QueryCondition> conList = new ArrayList<>();
                List<ApiColumn> cols = CacheUtil.getList(ApiColumn.class, inter.getModelTable().getOid());
                for (ApiColumn col : cols) {
                    if (col.getIsinit().equals("Y")) {
                        if (ObjectUtil.notEmptyOid(col.getModelTable())) {
                            if (StringUtil.notSpace(getParamsValue(col.getName() + ".oid"))) {
                                conList.add(QueryCondition.like(col.getName() + ".oid", getParamsValue(col.getName() + ".oid")));
                            }
                        } else {
                            if (FieldType.INT.toString().equals(col.getType())
                                    || FieldType.DOUBLE.toString().equals(col.getType())
                                    || FieldType.DATE.toString().equals(col.getType())) {
                                if (StringUtil.notSpace(getParamsValue(col.getName() + "_down"))) {
                                    conList.add(QueryCondition.ge(col.getName(), getParamsValue(col.getName() + "_down")));
                                }
                                if (StringUtil.notSpace(getParamsValue(col.getName() + "_up"))) {
                                    conList.add(QueryCondition.le(col.getName(), getParamsValue(col.getName() + "_up")));
                                }
                            } else if (StringUtil.notSpace(col.getDictOption()) || StringUtil.notSpace(col.getDictType())) {
                                if (StringUtil.notSpace(getParamsValue(col.getName()))) {
                                    conList.add(QueryCondition.eq(col.getName(), getParamsValue(col.getName())));
                                }
                            } else {
                                if (StringUtil.notSpace(getParamsValue(col.getName()))) {
                                    conList.add(QueryCondition.like(col.getName(), getParamsValue(col.getName())));
                                }
                            }
                        }
                    }
                }
                List<Map<String, Object>> list = TableQueryList.getList(inter.getModelTable().getOid(),
                        fields, getPage(),
                        QueryCondition.and(conList.toArray(new QueryCondition[]{})),
                        getOrder()
                );
                if(!ArrayUtil.isEmpty(inter.getDataHandler())){
                    List<JSONObject> ls=new ArrayList<>();
                    for(Map<String,Object> item : list){
                        ls.add(HandlerUtil.executes(new JSONObject(item),admin,inter.getDataHandler()));
                    }
                    result.push("list", ls);
                }else{
                    result.push("list", list);
                }
                msg = "查询成功";
            } else {
                throw new MException(this.getClass(), "接口类型错误");
            }
            tm.commit();
        }catch (Exception e){
            tm.rollback();
            throw e;
        }
        return result.push("msg",msg);
    }
    @RequestMeta(params = {"authId"})
    public JSONMessage getToken(String authId) throws Exception {
        verifyAdminOperPower("manage_api_power");
        ApiAuthinfo model= CacheUtil.get(ApiAuthinfo.class,authId);
        return new JSONMessage(0)
                .push("token",getService(ApiAuthinfoService.class).getToken(String.valueOf(new Date().getTime()),model.getAuthId(),model.getAuthKey()));
    }

    public VueResult selectTablePage() throws Exception {
        String tableOid=getParamsValue("tableOid");
        ApiTable apiTable=CacheUtil.get(ApiTable.class,tableOid);
        List<ApiColumn> cols=CacheUtil.getList(ApiColumn.class,apiTable.getOid());
        FromQueryList from=FromQueryList.from("a",apiTable.getOid());
        VueCollectResult result=getVueCollectResult(apiTable.getDescription(), from, actionUrl("selectTablePage"));
        result.addCol(collectIndexColumn());
        for(int i=0;i<cols.size();i++){
            ApiColumn col=cols.get(i);
            if("Y".equals(col.getIsinit())){
                String fk="f"+i;
                String field="#{a."+col.getName()+"} "+fk;
                String text=col.getDescription().split("\\|")[0];
                CollectColumn cc;
                if("DATE".equals(col.getType())){
                    cc=collectDateTimeColumn(text,field,140,true).setDateFormat(DateUtil.YYYY_MM_DD_HH_MM_SS);
                }else if("INT".equals(col.getType())){
                    cc=collectIntegerColumn(text,field,100,true);
                }else if("DOUBLE".equals(col.getType())){
                    cc=collectNumberColumn(text,field,120,true);
                }else{
                    int width=80+col.getLength();
                    if(width>350) width=350;
                    cc=collectTextColumn(text,field,width,true);
                }
                if(!StringUtil.isSpace(col.getDictType())){
                    cc.setDictType(col.getDictType());
                }else if(!StringUtil.isSpace(col.getDictOption())){
                    cc.setDisItems(DisplayItem.to(col.getDictOption().split(":|,")));
                }
                if(!StringUtil.isSpace(col.getModelClass())){
                    cc.setType(CollectColumnType.LINK)
                        .setLinkEvent(
                            new ListEvent(actionUrl(ApiTableAction.class,"toViewModel"), EventType.MODAL,600)
                                .addParam(Param.value("modelClass",col.getModelClass()))
                                .addParam(fk+"1",Param.field("oid","#{a."+col.getName()+"}"))
                        );
                }else if(ObjectUtil.notEmptyOid(col.getModelTable())) {
                    cc.setType(CollectColumnType.LINK)
                        .setLinkEvent(
                            new ListEvent(actionUrl(ApiTableAction.class,"toViewTable"), EventType.MODAL,600)
                                .addParam(Param.value("tableOid",col.getModelTable().getOid()))
                                .addParam(fk+"1",Param.field("oid","#{a."+col.getName()+"}"))
                        );
                }
                result.addCol(cc.setSort(true));
            }
        }
        result.addCol(collectSpaceColumn("选择",100, ListButton.back("选择", ButtonType.PRIMARY)
            .addParam("selectOid",Param.field("","#{a.oid}"))
        ).setFixed(Align.RIGHT));
        return result;

    }

    public JSONObject getModel() {
        return model;
    }

    public void setModel(JSONObject model) {
        this.model = model;
    }
}
